home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-09-09 | 29.2 KB | 1,006 lines | [TEXT/CWIE] |
- // Simple framework for Macintosh sample code
- //
- // David Hayward
- // Developer Technical Support
- // AppleLink: DEVSUPPORT
- //
- // Copyrite 1995, Apple Computer,Inc
- //
- // This file contains the framework's AppleEvent handlers
- //
- // 9/13/94 nick first cut
- // 12/13/94 david several modifications
-
- #include <Types.h>
- #include <Memory.h>
- #include <Gestalt.h>
- #include <Errors.h>
- #include <CodeFragments.h>
- #include <Processes.h>
- #include <AppleEvents.h>
- #include <QuickDraw.h>
- #include <QDOffScreen.h>
- #include <Windows.h>
- #include <Folders.h>
- #include <Files.h>
- #include <Drag.h>
-
- #include "aeUtils.h"
- #include "dragUtils.h"
-
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE GLOBALS
- |**| ==============================================================================
- \**/
- static Boolean acceptableDrag ;
- static long hilitedContentIndex ;
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE FUNCTION PROTOTYPES
- |**| ==============================================================================
- \**/
- static OSErr InstallDragZonesHandlers ( DragZonesHdl zones ) ;
- static OSErr RemoveDragZonesHandlers ( DragZonesHdl zones ) ;
- static pascal OSErr DragZoneTrackingHandler ( short theMessage, WindowRef theWindow, void *handlerRefCon, DragReference theDrag) ;
- static pascal OSErr DragZoneReceiveHandler ( WindowRef theWindow, void *handlerRefCon, DragReference drag ) ;
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE TYPEDEFS
- |**| ==============================================================================
- \**/
- typedef struct DragZoneRecvData
- {
- DragZoneHdl zone ;
- WindowRef window ;
- Point location ;
- DragZoneRecvUPP callback ;
- Size dataSize ;
- char *dataPtr[] ;
- } DragZoneRecvDataRec, *DragZoneRecvDataPtr, **DragZoneRecvDataHdl ;
-
- enum {
- kDraggingClass = 'drag',
- kDragDrawID = 'draw',
- kDragSendID = 'send',
- kDragReceiveID = 'recv',
- kDragTrackID = 'trak',
- kDragDragID = 'drag',
- keyPrivateData = 'priv'
- };
-
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE GLOBALS
- |**| ==============================================================================
- \**/
- OSErr gDrag_present_err = 1;
- OSErr gDrag_available_err = 1 ;
- OSErr gDrag_initialized_err = 1;
-
-
- /**\
- |**| ==============================================================================
- |**| PUBLIC FUNCTIONS
- |**| ==============================================================================
- \**/
-
-
- /*------------------------------------------------------------------------------*\
- Drag_present
- *------------------------------------------------------------------------------*
- This function returns noErr if drag and drop support is present
- (i.e passes gestalt) and returns an error otherwise.
- It also sets the private global gDrag_present_err based on the result.
- \*------------------------------------------------------------------------------*/
- OSErr Drag_present ( void )
- {
- OSErr err;
- long response;
-
- if ( !gDrag_present_err )
- return noErr;
-
- err = Gestalt(gestaltDragMgrAttr,&response) ;
- if (!err)
- if ((response & (1<<gestaltDragMgrPresent)) == 0 )
- err = 1 ; // should return something else
-
- #ifdef powerc
- // This is a sanity check to see if the PowerPC DragLib is installed
- // just in case we are "weak" against DragLib
- if (!err)
- if ( kUnresolvedCFragSymbolAddress == (long)NewDrag)
- err = 1; // QuickDraw GX is not available in Power Mac
- #endif
-
- gDrag_present_err = err;
- return err;
- }
-
-
- /*------------------------------------------------------------------------------*\
- Drag_available
- *------------------------------------------------------------------------------*
- This function returns noErr if drag and drop support is available
- (i.e present and initialized) to the application and returns an error otherwise.
- It also sets the global gDrag_available_err based on the result.
- \*------------------------------------------------------------------------------*/
- OSErr Drag_available ( void )
- {
- OSErr err;
-
- if ( !gDrag_available_err )
- return noErr;
-
- err = Drag_present();
- if ( !err )
- err = Drag_initialize();
-
- gDrag_available_err = err;
- return err ;
- }
-
- /*------------------------------------------------------------------------------*\
- Drag_initialize
- *------------------------------------------------------------------------------*
- This function initializes all the drag stuff.
- It should be called early in the application.
- \*------------------------------------------------------------------------------*/
- OSErr Drag_initialize ( void )
- {
- OSErr err;
-
- if ( !gDrag_initialized_err )
- return noErr;
-
- err = Drag_present();
- if ( !err )
- {
- err = RegisterDragAppleEvents();
- }
-
- gDrag_initialized_err = err;
- return err;
- }
-
-
- //-----------------------------------------------------------------------
- // DragIsInRect returns true if the current mouse is in the content
- // area of the window (but not necessarily in the visible rgn)
-
- Boolean DragIsInRect ( DragReference drag, WindowRef window, Rect *rect )
- {
- Point mousePt ;
- GrafPtr savePort ;
-
- (void) GetDragMouse( drag, &mousePt, nil ) ;
-
- GetPort( &savePort ) ;
- SetPort( (GrafPtr)window ) ;
- GlobalToLocal( &mousePt ) ;
- SetPort( savePort ) ;
-
- return PtInRect( mousePt, rect ) ;
- }
-
-
- //-----------------------------------------------------------------------
- // DragIsInSourceWindow returns true if the drag in progress
- // is in the same window it originated in
- //
- // DragIsInSourceWindow is called by the tracking and receive handlers
- //
- // Note that, if this application allowed items to be dragged within its windows,
- // this function would not be appropriate. Instead, hilighting would probably occur
- // in the source window when the dragHasLeftSourceWindow flag is set, and the receive
- // handler wouldn't check this at all
-
- Boolean DragIsInSourceWindow ( DragReference drag )
- {
- DragAttributes currDragFlags;
- (void) GetDragAttributes( drag, &currDragFlags ) ;
- return ( (currDragFlags & kDragInsideSenderWindow) != 0) ;
- }
-
-
- //
- // DropLocationIsFinderTrash
- //
- // Returns true if the given dropLocation AEDesc is a descriptor of the Finder's Trash.
- //
-
- Boolean DropLocationIsFinderTrash ( DragReference drag )
- {
- AEDesc dropLocation ;
- OSErr result;
- AEDesc dropSpec;
- FSSpec *theSpec;
- CInfoPBRec thePB;
- short trashVRefNum;
- long trashDirID;
-
- GetDropLocation( drag, &dropLocation ) ;
-
- // Coerce the dropLocation descriptor to an FSSpec. If there's no dropLocation or
- // it can't be coerced into an FSSpec, then it couldn't have been the Trash.
-
- if ((dropLocation.descriptorType != typeNull) &&
- (AECoerceDesc(&dropLocation, typeFSS, &dropSpec) == noErr))
- {
- HLock(dropSpec.dataHandle) ;
- theSpec = (FSSpec *) *dropSpec.dataHandle;
-
- // Get the directory ID of the given dropLocation object.
- thePB.dirInfo.ioCompletion = 0L;
- thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name;
- thePB.dirInfo.ioVRefNum = theSpec->vRefNum;
- thePB.dirInfo.ioFDirIndex = 0;
- thePB.dirInfo.ioDrDirID = theSpec->parID;
-
- result = PBGetCatInfoSync(&thePB) ;
-
- HUnlock(dropSpec.dataHandle) ;
- AEDisposeDesc(&dropSpec) ;
-
- if (result != noErr)
- return false ;
-
- // If the result is not a directory, it must not be the Trash.
- if (!(thePB.dirInfo.ioFlAttrib & (1 << 4)))
- return false ;
-
- // Get information about the Trash folder.
- FindFolder(theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID) ;
-
- // If the directory ID of the dropLocation object is the same as the directory ID
- // returned by FindFolder, then the drop must have occurred into the Trash.
- if (thePB.dirInfo.ioDrDirID == trashDirID)
- return true ;
- }
-
- return false ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- NewDragZonesHandle
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- DragZonesHdl NewDragZones ( WindowRef window )
- {
- DragZonesHdl zones ;
-
- zones = (DragZonesHdl) NewHandleClear( sizeof(DragZonesRec) ) ;
- if (zones==nil) return nil ;
-
- (**zones).count = 0 ;
- (**zones).window = window;
-
- if (InstallDragZonesHandlers(zones) != noErr)
- {
- DisposeHandle( (Handle)zones );
- zones = nil;
- }
-
- return zones ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- DisposeDragZonesHandle
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- void DisposeDragZonesHandle ( DragZonesHdl zones )
- {
- DragZoneHdl zone ;
-
- RemoveDragZonesHandlers( zones ) ;
-
- while ( (**zones).count )
- {
- (**zones).count--;
- zone = (**zones).item[(**zones).count];
- DisposeRoutineDescriptor( (**zone).dragRecvUPP ) ;
- DisposeHandle( (Handle)zone );
- }
-
- DisposeHandle( (Handle)zones );
-
- return ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- AddDragZone
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- OSErr AddDragZone ( DragZonesHdl zones, DragZonePtr zone )
- {
- DragZoneHdl newZone ;
- long newCount ;
- Size newHandleSize ;
- OSErr err ;
-
- newCount = (**zones).count + 1 ;
- newHandleSize = sizeof(DragZonesRec) + newCount*sizeof(DragZoneHdl) ;
- SetHandleSize ( (Handle)zones, newHandleSize ) ;
- err = MemError() ;
- if (err) return err ;
-
- newZone = (DragZoneHdl) NewHandleClear( sizeof(DragZoneRec) ) ;
- if (newZone==nil) return MemError() ;
-
- **newZone = *zone ;
- (**zones).item[newCount-1] = newZone ;
- (**zones).count = newCount ;
-
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- DelDragZone
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- OSErr DelDragZone ( DragZonesHdl zones, DragZoneHdl zone )
- {
- long index, newIndex ;
- long oldCount, newCount ;
- Size newHandleSize ;
- OSErr err ;
-
- oldCount = (**zones).count ;
- newCount = oldCount - 1 ;
-
- for ( index=newIndex=0; index<oldCount; index++ )
- if ( (**zones).item[index] != zone )
- {
- (**zones).item[newIndex] = (**zones).item[index] ;
- newIndex++ ;
- }
-
- (**zones).count = newCount ;
-
- newHandleSize = sizeof(DragZonesRec) + newCount*sizeof(DragZoneHdl) ;
- SetHandleSize ( (Handle)zones, newHandleSize ) ;
- err = MemError() ;
-
- DisposeHandle( (Handle)zone ) ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- FindDragZones
- *------------------------------------------------------------------------------*
- This routine searches through the DragZones data structure to locate those
- DragZones that have given flavor and/or fileType. It can be used either
- to count the number of matches or to return the matches in the result buffer.
- The logic is basically the following:
- if result buffer is nil
- return num of DragZones that match the flavor and/or fileType parameters
- the index and count fields are ignored
- else
- copy into result buffer up to count DragZoneHdls that match the flavor
- and/or fileType parameters starting with the index-th match
- return the the number of DragZoneHdl copied into the buffer
- \*------------------------------------------------------------------------------*/
- short FindDragZones ( DragZonesHdl zones,
- FlavorType flavor,
- OSType HFSfileType,
- short index,
- short count,
- DragZoneHdl *result )
- {
- long z ;
- DragZoneHdl zone ;
- short n = 0;
- short stopCount, foundCount;
- Boolean foundOne, sameFlavor, sameFileType;
-
- stopCount = count ;
- foundCount = z = 0 ;
-
- if ((**zones).count==0) return 0 ; // no zones are in the DragZonesHdl
-
- do {
- zone = (**zones).item[z] ;
- foundOne = false;
- if ( zone != nil )
- {
- if ( flavor==nil )
- foundOne = true;
- else
- {
- sameFlavor = ( flavor==(**zone).flavor ) ;
- sameFileType = ( HFSfileType==(**zone).HFSfileType ) ;
-
- if ( sameFlavor )
- {
- if (flavor!=flavorTypeHFS)
- foundOne = true;
- else if ( sameFileType )
- foundOne = true;
- }
- }
-
- if (foundOne)
- {
- if ( result==nil )
- foundCount++ ;
- else
- {
- n++;
- if (n>=index)
- {
- foundCount++ ;
- result[foundCount-1] = zone;
- }
- }
- }
- }
- z++ ;
-
- } while ( (z!=(**zones).count) && ((foundCount<stopCount) || (result==nil)) ) ;
-
- return foundCount;
- }
-
-
- /**\
- |**| ==============================================================================
- |**| PRIVATE FUNCTIONS
- |**| ==============================================================================
- \**/
-
-
- /*------------------------------------------------------------------------------*\
- InstallDragZonesHandlers
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- static OSErr InstallDragZonesHandlers ( DragZonesHdl zones )
- {
- OSErr errT, errR ;
- WindowRef window;
-
- window = (**zones).window;
- (**zones).trackingHandler = NewDragTrackingHandlerProc(DragZoneTrackingHandler) ;
- (**zones).receiveHandler = NewDragReceiveHandlerProc(DragZoneReceiveHandler) ;
-
- errT = InstallTrackingHandler( (**zones).trackingHandler, (WindowPtr)window, (void *)zones ) ;
- errR = InstallReceiveHandler( (**zones).receiveHandler, (WindowPtr)window, (void *)zones ) ;
-
- if (errT) DisposeRoutineDescriptor( (**zones).trackingHandler ) ;
- if (errR) DisposeRoutineDescriptor( (**zones).receiveHandler ) ;
-
- if (errT) (**zones).trackingHandler = nil ;
- if (errR) (**zones).receiveHandler = nil ;
-
- return (errT) ? (errT) : (errR) ; // return one of the errors
- }
-
-
- /*------------------------------------------------------------------------------*\
- RemoveDragZonesHandlers
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- static OSErr RemoveDragZonesHandlers ( DragZonesHdl zones )
- {
- OSErr errT, errR ;
- WindowRef window;
-
- window = (**zones).window;
- errT = RemoveTrackingHandler( (**zones).trackingHandler, (WindowPtr)window ) ;
- errR = RemoveReceiveHandler( (**zones).receiveHandler, (WindowPtr)window ) ;
-
- if (!errT) DisposeRoutineDescriptor( (**zones).trackingHandler ) ;
- if (!errR) DisposeRoutineDescriptor( (**zones).receiveHandler ) ;
-
- if (!errT) (**zones).trackingHandler = nil ;
- if (!errR) (**zones).receiveHandler = nil ;
-
- return (errT) ? (errT) : (errR) ; // return one of the errors
- }
-
-
- /*------------------------------------------------------------------------------*\
- DragZoneTrackingHandler
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- static pascal OSErr DragZoneTrackingHandler ( short theMessage, WindowRef theWindow,
- void *handlerRefCon, DragReference drag )
- {
- OSErr err ;
- RgnHandle tempRgn;
- Rect rect;
- long mouseContentIndex = -1 ;
- OSErr retCode;
- DragZonesHdl zones = (DragZonesHdl)handlerRefCon;
-
- retCode = noErr ;
- switch (theMessage)
- {
- case kDragTrackingEnterHandler:
- break;
-
- case kDragTrackingEnterWindow:
- // determine if the items are acceptable and store that
- // flag in the globals, plus reset the hilighted global flag
- acceptableDrag = DragZoneItemsAcceptable(drag,zones) ;
- hilitedContentIndex = -1 ;
- break;
-
- case kDragTrackingInWindow:
- case kDragTrackingLeaveWindow:
-
- // highlighting of the window during a drag is done here.
- // Do it only if we can accept these items and we're not in the source window...
- if ( acceptableDrag && !DragIsInSourceWindow(drag) )
- {
- // unless the mouse is leaving the visible area of the
- // window, check if it's in the window's content region
-
- if (theMessage == kDragTrackingLeaveWindow)
- mouseContentIndex = -1L;
- else
- mouseContentIndex = DragZoneIsInWhichRect( drag, theWindow, zones ) ;
-
- // if the mouse is not in the content region
- // and the window is hilighted, erase the hilight
-
- if ( mouseContentIndex!=hilitedContentIndex )
- {
- // erase the hilight and restore the port
- err = HideDragHilite( drag ) ;
- if ( !err )
- hilitedContentIndex = -1; // remember that nothing hilighted
- }
-
- // if the mouse is in the content area and the window
- // is not yet hilighted, then do the hilighting
-
- if ( mouseContentIndex>=0 &&
- mouseContentIndex!=hilitedContentIndex )
- {
- // make a region bordering the window content
- tempRgn = NewRgn() ;
- rect = (**((**zones).item[mouseContentIndex])).rect ;
- RectRgn(tempRgn, &rect ) ;
-
- // draw the hilight
- err = ShowDragHilite( drag, tempRgn, true) ;
- if ( !err )
- hilitedContentIndex = mouseContentIndex ; // remember which is hilited
-
- // free up the region
- DisposeRgn(tempRgn) ;
- }
- }
- break;
-
- // do nothing for the leaveHandler message
- case kDragTrackingLeaveHandler:
- break;
-
- // let the drag manager know if we didn't recognize the message
- default:
- retCode = paramErr ;
- break;
- }
-
- return retCode;
- }
-
-
- /*------------------------------------------------------------------------------*\
- DragZoneReceiveHandler
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- static pascal OSErr DragZoneReceiveHandler ( WindowRef theWindow, void *handlerRefCon, DragReference drag )
- {
- OSErr err ;
- ItemReference theItem ;
- DragAttributes attributes ;
- Size dataSize ;
- short mouseDownModifiers, mouseUpModifiers ;
- Point mouseLoc ;
- Handle dragData = nil ;
- long mouseContentIndex ;
- DragZoneHdl iZone ;
- FlavorType iFlavor ;
- DragZonesHdl zones = (DragZonesHdl)handlerRefCon;
-
- if (!DragZoneItemsAcceptable(drag,zones) ||
- DragIsInSourceWindow(drag) )
- return dragNotAcceptedErr ;
-
- mouseContentIndex = DragZoneIsInWhichRect( drag, theWindow, zones ) ;
- if ( mouseContentIndex <0 )
- return dragNotAcceptedErr ;
-
- // We will only support one item, so get its reference number.
- err = GetDragItemReferenceNumber( drag, 1, &theItem) ;
- if ( err ) return err;
-
- GetDragAttributes( drag, &attributes) ;
- GetDragModifiers( drag, 0L, &mouseDownModifiers, &mouseUpModifiers) ;
- GetDragMouse( drag, &mouseLoc, nil ) ;
-
- iZone = (**zones).item[mouseContentIndex] ;
- iFlavor = (**iZone).flavor ;
-
- // Get the item's reference, so we can refer to it.
- GetDragItemReferenceNumber( drag, 1, &theItem) ;
-
- err = GetFlavorDataSize( drag,theItem,iFlavor,&dataSize ) ;
- if ( err ) return err;
-
- // so we either have nothing or something (in the form of prof or PICT data)
- if ( !err )
- {
- DragZoneRecvUPP theDragZoneRecvUPP;
-
- // create a handle large enough for the data
- dragData = NewHandle( dataSize ) ;
- if( dragData == nil )
- return MemError() ;
-
- // Lock and load, I dunno if GetFlavorData moves memory, I'm just assuming it may...
- // passing (**dragData) in dereferenced - ASSUMES the handle is locked
- HLock( (Handle)dragData ) ;
- GetFlavorData( drag, theItem, iFlavor, *dragData, &dataSize, 0L) ;
- HUnlock( (Handle)dragData ) ;
-
- theDragZoneRecvUPP = (**(**zones).item[mouseContentIndex]).dragRecvUPP ;
-
- /* err = CallDragZoneRecvProc(
- theDragZoneRecvUPP,
- iZone,
- theWindow,
- mouseLoc,
- dragData ) ;
- */
- // send it to ourselves
- err = SendDragRecv(
- iZone,
- theWindow,
- mouseLoc,
- dragData,
- theDragZoneRecvUPP ) ;
-
- // and dispose of the data and upp
- DisposeHandle( dragData ) ;
- DisposeRoutineDescriptor( theDragZoneRecvUPP ) ;
-
- if ( attributes & kDragHasLeftSenderWindow )
- HideDragHilite( drag ) ;
- }
-
- //DebugStr("\pleaving recv handlr") ;
- return err ;
- }
-
-
-
- /*------------------------------------------------------------------------------*\
- DragZoneIsInWhichRect
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- long DragZoneIsInWhichRect ( DragReference drag, WindowRef theWindow, DragZonesHdl zones )
- {
- OSErr err ;
- unsigned short totalItems ;
- long count, i ;
- long result ;
- ItemReference itemRef;
- Size dataSize;
- HFSFlavor theHFSFlavor ;
- FlavorFlags theFlavorFlags;
- DragZoneHdl iZone ;
- FlavorType iFlavor ;
- Rect iRect ;
-
- result = -1;
-
- if ( !DragZoneItemsAcceptable(drag,zones) )
- return 0 ;
-
- // for now, this app can only accept the drag of a single item
- err = CountDragItems( drag, &totalItems ) ;
- if ( err || totalItems != 1) return 0;
-
- // get the reference number of the dragged item
- err = GetDragItemReferenceNumber( drag, 1, &itemRef ) ;
- if ( err ) return 0;
-
- // use GetFlavorFlags to check on flavor existence of PICT data
- // without forcing translation
-
- // for each item in the struct, check to see, if the drag has the flavor of data needed
- // and if the drag is currently within the items bound rect.
- // when we find the first items that passes this test, return its index
- count = (**zones).count ;
- for ( i=0; (result<0) && (i<count); i++ )
- {
- iZone = (**zones).item[i] ;
- iFlavor = (**iZone).flavor ;
- iRect = (**iZone).rect ;
-
- if ( DragIsInRect( drag, theWindow, &iRect ) )
- {
- err = GetFlavorFlags( drag, itemRef, iFlavor, &theFlavorFlags) ;
- if ( !err )
- {
- if ( iFlavor==flavorTypeHFS )
- {
- dataSize = sizeof(HFSFlavor) ;
- err = GetFlavorData( drag, itemRef, iFlavor, &theHFSFlavor, &dataSize, 0 ) ;
- if ( (!err) && (theHFSFlavor.fileType == (**iZone).HFSfileType ) )
- result = i;
- }
- else
- result = i;
- }
- }
- }
- return result;
- }
-
-
- /*------------------------------------------------------------------------------*\
- DragZoneItemsAcceptable
- *------------------------------------------------------------------------------*
- \*------------------------------------------------------------------------------*/
- Boolean DragZoneItemsAcceptable ( DragReference drag, DragZonesHdl zones )
- {
- OSErr err ;
- unsigned short totalItems;
- long count, i ;
- ItemReference itemRef;
- Boolean result ;
- Size dataSize;
- HFSFlavor theHFSFlavor ;
- FlavorFlags theFlavorFlags;
- DragZoneHdl iZone ;
- FlavorType iFlavor ;
-
- result = false;
-
- // for now, this app can only accept the drag of a single item
- err = CountDragItems( drag, &totalItems) ;
- if ( err || totalItems!=1) return false;
-
- // get the reference number of the dragged item
- err = GetDragItemReferenceNumber( drag, 1, &itemRef ) ;
- if ( err ) return false;
-
- // for each item in the struct, check to see, if the drag has the flavor of data needed
- // if any of the items pass this test then return true
-
- count = (**zones).count ;
- for ( i=0; (!result) && (i<count); i++ )
- {
- iZone = (**zones).item[i] ;
- iFlavor = (**iZone).flavor ;
-
- err = GetFlavorFlags( drag, itemRef, iFlavor, &theFlavorFlags ) ;
- if ( !err )
- {
- if ( iFlavor==flavorTypeHFS )
- {
- dataSize = sizeof(HFSFlavor) ;
- err = GetFlavorData( drag, itemRef, iFlavor, &theHFSFlavor, &dataSize, 0 ) ;
- if ( (!err) && (theHFSFlavor.fileType == (**iZone).HFSfileType ) )
- result = true;
- }
- else
- result = true;
- }
- }
-
- return result;
- }
-
-
-
- /*------------------------------------------------------------------------------*\
- RegisterDragAppleEvents
- *------------------------------------------------------------------------------*
- called to register our drag apple event handler
- \*------------------------------------------------------------------------------*/
- OSErr RegisterDragAppleEvents ( void )
- {
- OSErr err ;
-
- err = AEInstallEventHandler( kDraggingClass, kDragReceiveID,
- NewAEEventHandlerProc(HandleDragRecv),
- 0L, false ) ;
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- HandleDragRecv
- *------------------------------------------------------------------------------*
- This routine processes the Drag Receive AppleEvent
- and passes it to the framework.
- \*------------------------------------------------------------------------------*/
- pascal OSErr HandleDragRecv ( AppleEvent *theAppleEvent, AppleEvent *reply, long refCon )
- {
- AEDesc myDesc ;
- OSErr err = noErr ;
- OSErr ignoreErr ;
- Handle dataHdl ;
- DragZoneRecvDataHdl thePackage = nil ;
- Size thePackageSize ;
- DragZoneHdl theZone ;
- WindowRef theWindow ;
- Point theLocation ;
- DragZoneRecvUPP theCallback ;
- Size dataHdlSize ;
-
- err = AEGetParamDesc(theAppleEvent,keyPrivateData,typeChar,&myDesc) ;
- if ( !err )
- {
- // try to load all of the items we stuffed into the apple event
-
- thePackage = (DragZoneRecvDataHdl)myDesc.dataHandle ;
- thePackageSize = GetHandleSize( (Handle)thePackage) ;
-
- // get the fields from the packaged data
- theZone = (**thePackage).zone ;
- theWindow = (**thePackage).window ;
- theLocation = (**thePackage).location ;
- theCallback = (**thePackage).callback ;
- dataHdlSize = (**thePackage).dataSize ;
-
- // sanity check
- if( thePackageSize != (dataHdlSize + sizeof(DragZoneRecvDataRec)) )
- {
- ignoreErr = AEDisposeDesc(&myDesc) ;
- return paramErr ;
- }
-
- // Lock them down
- MoveHHi( (Handle)thePackage ) ;
- HLock( (Handle)thePackage ) ;
-
- // copy the data from the descriptor to a new handle
- err = PtrToHand( (**thePackage).dataPtr, &dataHdl, dataHdlSize) ;
- DisposeHandle( (Handle)thePackage ) ;
- if ( err ) // check we could create the data handle OK
- {
- ignoreErr = AEDisposeDesc(&myDesc) ;
- return err ;
- }
-
- // we need to get rid of the descriptor (and thePackage) to save on memory
- err = AEDisposeDesc(&myDesc) ;
-
- // process the information from the drag
- if (err == noErr)
- CallDragZoneRecvProc(theCallback, theZone, theWindow, theLocation, dataHdl) ;
-
- // we can free up the memory now...
- DisposeHandle( dataHdl ) ;
- }
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- SendDragRecv
- *------------------------------------------------------------------------------*
- This routine sends a drag receive Apple Event to this application.
- \*------------------------------------------------------------------------------*/
- OSErr SendDragRecv ( DragZoneHdl theZone, WindowRef theWindow, Point theLocation,
- Handle dataHdl, DragZoneRecvUPP theDragZoneRecvUPP )
- {
- AppleEvent myAppleEvent;
- AppleEvent defReply;
- OSErr err ;
- char cMemTags ;
- DragZoneRecvDataHdl thePackage = nil ;
- Size thePackageSize ;
-
-
- cMemTags = HGetState( dataHdl ) ; // save the state of the handle in case it
- // was already locked before we were called
-
- myAppleEvent.dataHandle = nil;
- defReply.dataHandle = nil;
-
- // the static pSelfAddress that we create an usually use will cause the
- // AE handler to be caused directly (less overhead). We DON'T WANT THAT
- // to happen here. The reason being that the handler for this event needs
- // to be called in our main event loop, not directly at the send. Doing things
- // this way lets us get out of the Drag Managers context, back into our own.
- // that in turn lets us use a high level debugger.
-
- err = AECreateAppleEvent( kDraggingClass,
- kDragReceiveID,
- &gSelfPSNAddress,
- kAutoGenerateReturnID,
- kAnyTransactionID,
- &myAppleEvent ) ;
- if ( err ) return err ;
-
- // create a new data handle to hold the data the user just dragged in
- thePackage = (DragZoneRecvDataHdl) NewHandle( sizeof(DragZoneRecvDataRec) ) ;
- if ( thePackage == nil ) return MemError() ;
-
- (**thePackage).zone = theZone ;
- (**thePackage).window = theWindow ;
- (**thePackage).location = theLocation ;
- (**thePackage).callback = theDragZoneRecvUPP ;
- (**thePackage).dataSize = GetHandleSize(dataHdl) ;
-
- // append the dataHdl to the end of thePackage handle
- err = HandAndHand( dataHdl,(Handle)thePackage ) ;
- if ( err ) return MemError() ;
- thePackageSize = GetHandleSize( (Handle)thePackage ) ;
-
- // Lock it down
- MoveHHi( (Handle)thePackage ) ;
- HLock( (Handle)thePackage ) ;
-
- // Put Params into our event and send it
- err = AEPutParamPtr( &myAppleEvent,
- keyPrivateData,
- typeChar,
- *thePackage,
- thePackageSize ) ;
- if ( err ) return err ;
-
- // restore the state of the handle (effectively the same as HUnlock)
- HSetState( dataHdl, cMemTags) ;
-
- err = AESend( &myAppleEvent,
- &defReply,
- kAENoReply+kAENeverInteract,
- kAENormalPriority,
- kAEDefaultTimeout,
- nil,
- nil) ;
- if ( err ) return err ;
-
- if ( myAppleEvent.dataHandle )
- err = AEDisposeDesc( &myAppleEvent ) ;
-
- // we dont want to dispose of thePackage here because
- // whe don't know if the AppleEvent has been handled yet
-
- return err ;
- }
-
-
- /*------------------------------------------------------------------------------*\
- OutlineRegion
- *------------------------------------------------------------------------------*
- This routine modifies a rgn to be an outline of its former self.
- \*------------------------------------------------------------------------------*/
- OSErr OutlineRegion ( RgnHandle theRgn )
- {
- RgnHandle tempRgn;
-
- // create a temp rgn that is a copy of the rgn passed in
- tempRgn = NewRgn();
- CopyRgn(theRgn, tempRgn);
-
- // inset the temp rgn
- InsetRgn(tempRgn, 1, 1);
-
- // subtract the temp rgn from the rgn passed in
- DiffRgn(theRgn, tempRgn, theRgn);
- DisposeRgn(tempRgn);
-
- return noErr ;
- }
-
-
-